package com.lambkit.data;

import java.sql.Date;
import java.sql.Timestamp;
import java.util.List;

import cn.hutool.core.util.StrUtil;
import com.lambkit.db.dialect.DialectFactory;
import com.lambkit.db.dialect.IDialect;
import com.lambkit.db.dialect.PostgreSqlDialect;
import com.lambkit.db.meta.ColumnMeta;
import com.lambkit.db.meta.TableMeta;
import com.lambkit.db.mgr.IField;
import com.lambkit.db.mgr.ITable;
import com.lambkit.db.sql.Columns;

public class DataType {
	private String name;
	private ITable model;
	private TableMeta meta;
	private List<? extends IField> fieldList;
	
	public ITable getModel() {
		return model;
	}

	public void setModel(ITable model) {
		this.model = model;
	}

	public TableMeta getMeta() {
		return meta;
	}

	public void setMeta(TableMeta meta) {
		this.meta = meta;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<? extends IField> getFieldList() {
		return fieldList;
	}

	public void setFieldList(List<? extends IField> list) {
		this.fieldList = list;
	}
	
	public IField getField(String fieldName) {
		for (IField iField : fieldList) {
			if(iField.getName().equals(fieldName)) {
				return iField;
			}
		}
		return null;
	}

	/******/
	public String getPrimaryKey() {
		if(meta!=null) {
			return meta.getPrimaryKey();
		} else {
			return null;
		}
	}
	
	public Object getId() {
		if(model!=null) {
			return model.getId();
		} else {
			return null;
		}
	}
	
	public String getTitle() {
		if(model!=null) {
			return model.getTitle();
		} else {
			return null;
		}
	}
	
	public String getConfigName() {
		return meta !=null ? meta.getConfigName() : null;
	}

	public IDialect getDialect() {
		if(meta!=null) {
			String dialectName = meta.getDialect();
			return DialectFactory.create(dialectName);
		}
		return null;
	}


	public boolean hasColumn(String fldName) {
		if(StrUtil.isBlank(fldName)) {
			return false;
		}
		if(fieldList!=null) {
			for (IField iField : fieldList) {
				if(fldName.equals(iField.getName())) {
					return true;
				}
			}
		} else if(meta!=null && meta.getColumnMetas()!=null) {
			for (ColumnMeta column : meta.getColumnMetas()) {
				if(fldName.equals(column.getName())) {
					return true;
				}
			}
		}
		return false;
	}
	
	public Object getValue(String type, String value) {
		type = type.toLowerCase();
 		if(type.startsWith("bigint") || type.startsWith("bigserial") || type.startsWith("int8") || type.equals("int unsigned")) {
			 return Long.parseLong(value);
		}
 		else if(type.startsWith("int") || type.startsWith("serial") || type.startsWith("tinyint")) {
			 return Integer.parseInt(value);
		}
 		else if(type.startsWith("float")) {
			 return Float.parseFloat(value);
		}
 		else if(type.startsWith("double")) {
			 return Double.parseDouble(value);
		}
 		else if(type.startsWith("num")) {
			 return Double.parseDouble(value);//numeric,number
		}
 		else if(type.startsWith("date")) {
			 return Date.valueOf(value);
		}
 		else if(type.startsWith("datetime")) {
			 return Timestamp.valueOf(value);
		}
 		else if(type.startsWith("timestamp")) {
			 return Timestamp.valueOf(value);
		}
 		else {
			 return value;
		}
 	}
	/////////////////////////////////////////////////
	
	public String getLoadColumns(String alias) {
		if(StrUtil.isNotBlank(alias)) {
			alias = alias.trim();
			alias = alias.endsWith(".") ? alias.substring(0, alias.length()-1) : alias;
			alias = settingNameOfDialect(alias, getDialect());
			alias += ".";
		}
		StringBuilder sb = new StringBuilder();
		List<? extends IField> flds = getFieldList();
		for(int i=0; i<flds.size();i++) {
			if(flds.get(i).getIskey().equals("Y") || flds.get(i).getIsview().equals("Y") 
					|| flds.get(i).getIsselect().equals("Y") || flds.get(i).getIsedit().equals("Y")) {
				if(flds.get(i)==null || StrUtil.isBlank(flds.get(i).getName())) {
					continue;
				}
				sb.append(",").append(alias).append(settingNameOfDialect(flds.get(i).getName(), getDialect()));
			}
		}
		String fldnames = sb.toString();
		if(fldnames.length() > 1) {
			fldnames = fldnames.substring(1);
		}
		if(fldnames.trim().length() < 1) {
			fldnames = alias+"*";
		}
		return fldnames;
	}
	
	protected String settingNameOfDialect(String name, IDialect dialect) {
		if(StrUtil.isBlank(name)) {
			return name;
		}
		if(dialect!=null) {
			if(dialect instanceof PostgreSqlDialect) {
				return "\"" + name + "\"";
			}
		}
		return name;
	}
	
	protected String sql4FindById(Object id) {
		String pkname = getPrimaryKey();
		return getDialect().selectSqlByColumns(getName(), getLoadColumns(""), Columns.create(pkname, id), "", null);
	} 
}
